import axios, { AxiosError, CancelTokenSource } from 'axios';

import ssoAuth from '@hb/sso-auth2';

import { formatRequestParams } from './format';
import Catcher from './requestErrCatch';

declare module 'axios' {
  export interface AxiosRequestConfig {
    noToken?: boolean;
    noValidate?: boolean;
    noGlobalMessage?: boolean;
  }
}

export type StandardResponse<T = unknown> = {
  code?: number;
  errorCode?: number;
  status?: number;
  msg?: string;
  info?: string;
  data: T;
};

export const cancelTokenList: CancelTokenSource[] = [];

const service = axios.create({
  timeout: 15000,
});

service.interceptors.request.use((conf) => {
  const config = conf;
  if (!config.noToken) {
    config.headers = {
      token: ssoAuth.token,
      ...((config.headers as Record<string, unknown>) || {}),
    };
  }
  // 全局CancelToken
  const source = axios.CancelToken.source();
  cancelTokenList.push(source);
  config.cancelToken = source.token;
  // 过滤请求参数中的null 和 undefined 字段
  if (config.method == 'post') {
    config.data = formatRequestParams(config.data);
  }
  return config;
});

service.interceptors.response.use(
  (response) => {
    const { config } = response;
    // 清空并处理全局CancelToken List
    cancelTokenList.length = 0;
    cancelTokenList.push(
      ...cancelTokenList.filter((x) => x.token !== config.cancelToken),
    );

    // 各种返回状况处理
    const res = response.data as StandardResponse;
    if (!config.noValidate) {
      if (
        res.code !== 0 &&
        res.status !== 1 &&
        res.errorCode !== 0 &&
        res.status !== -2
      ) {
        Catcher(response, false, config.noGlobalMessage);
      }
    }
    return response.data;
  },
  (error: AxiosError) => {
    if (error.message === 'cancel') {
      throw error;
    }

    if (error.response)
      Catcher(error.response, true, error.config.noGlobalMessage);
  },
);

export default service;
